﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Workflow_Core_API.Persisted;
using WorkflowCore.Interface;
using WorkflowCore.Persistence.EntityFramework.Services;
using WorkflowCore.Service.Dto.Input;
using WorkflowCore.Service.Persisted;
using Newtonsoft.Json;
using WorkflowCore.Service.Manger;
using THE_WIND_RISES.Common.Dtos;
using WorkflowCore.Service.Dto.Fundamentals;
using WorkflowCore.Service.Strps;

namespace WorkflowCore.Service.Service
{
    public class WorkflowServer : IWorkflowServer
    {
        //启动、停止、管理工作流
        private readonly IWorkflowHost _workflowHost;
        //上下文
        public readonly WorkflowCoreDbcontext _dbcontext;
        //注册、查询、管理工作流
        private readonly IWorkflowRegistry workflowRegistry;
        private readonly IWorkflowManger workflowManger;
        private readonly GetWorkflowData getWorkflowData;

        public WorkflowServer(IWorkflowHost workflowHost, WorkflowCoreDbcontext dbcontext, IWorkflowRegistry workflowRegistry, IWorkflowManger workflowManger, GetWorkflowData getWorkflowData)
        {
            _workflowHost = workflowHost;
            _dbcontext = dbcontext;
            this.workflowRegistry = workflowRegistry;
            this.workflowManger = workflowManger;
            this.getWorkflowData = getWorkflowData;
            this.getWorkflowData = getWorkflowData;
        }

        /// <summary>
        /// 流程定义
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Results_<int> AddDefinition(WorkflowDefinitionInput Input)
        {
            //查询自带的表中是否存在此工作流
            if (workflowRegistry.IsRegistered(Input.WorkflowDefinitionId, Input.Version))
            {
                return Results_<int>.FailResult("流程已注册");
            }
            //实例化一个流程模型
            var definition = new PersistedWorkflowDefinition
            {
                Id = Guid.NewGuid(),
                Title = Input.Title,
                Version = Input.Version,
                WorkflowDefinitionId = Input.WorkflowDefinitionId,
                DataType = $"{typeof(Dictionary<string, object>).FullName},{typeof(Dictionary<string, object>).Assembly.FullName}",
                StepNodes = JsonConvert.SerializeObject(Input.Steps),
                IsLastVersion = true,
                CallbackUrl = "",
            };
            //给数据库中自定义的模型表添加值
            _dbcontext.persistedWorkflowDefinition.Add(definition);
            //更新数据库
            _dbcontext.SaveChanges();
            workflowManger.AddDefinition(definition);

            foreach (var item in Input.Steps)
            {
                foreach (var item2 in item.Detail.AuditPersons)
                {
                    var UserData = new WorkflowCoreUser()
                    {
                        Id = 0,
                        WorkflowCoreUserId = item2,
                        StepId = item.StepId,
                        WorkflowCoreId = Input.WorkflowDefinitionId,
                        CreateTime = DateTime.Now,
                        IsWorkflowCoreUserState = false
                    };
                    _dbcontext.WorkflowCoreUser.Add(UserData);
                    //更新数据库
                    _dbcontext.SaveChanges();
                }
            }

            workflowManger.AddDefinition(definition);
            return Results_<int>.SuccessResult("流程定义添加成功");
        }
        /// <summary>
        /// 发起流程
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Results_<string> StartWorkflow(WorkflowLaunchInput Input)
        {
            var Data = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(Input));
            var WorkflowId = Input.WorkflowId;
            if (string.IsNullOrEmpty(WorkflowId))
            {
                WorkflowId = _workflowHost.StartWorkflow(Input.WorkflowDefinitionId, Input.Version, Data, "").Result;
                var WorkflowInstanceData = new PersistedWorkflowInstance
                {
                    WorkflowInstanceId = WorkflowId,
                    WorkflowDefinitionId = Input.WorkflowDefinitionId,
                    Title = Input.Title,
                    FormFields = Convert.ToString(Input.FormContent),
                    ApplicantUserId = Input.UserId,
                    CurrentStepId = nameof(StartStep),
                    CurrentStepName = nameof(StartStep),
                    Status = WorkflowInstanceStatus.WorkflowStart,
                    ApplicantUserName = Input.UserName
                };
                _dbcontext.persistedWorkflowInstance.Add(WorkflowInstanceData);
            }
            else
            {
                //查找需要重新发起的流程
                var WorkflowInstanceData = _dbcontext.persistedWorkflowInstance.FirstOrDefault(x => x.WorkflowInstanceId == Input.WorkflowId);
                //更新数据
                WorkflowInstanceData.Title = Input.Title;
                WorkflowInstanceData.ApplicantTime = DateTime.Now;
                //WorkflowInstanceData.FormFields=JsonConvert.SerializeObject(Input.FormContent);
                //查询对应的审批单
                var audit = _dbcontext.persistedWorkflowAuditor.FirstOrDefault(x => x.OperateType == OperateType.Approval && x.WorkflowId == Input.WorkflowId && x.UserId == Input.UserId);
                audit.AuditTime = DateTime.Now;
                audit.OperateType = OperateType.Start;
                audit.Status = WorkFlowAuditStatus.Pass;

                _workflowHost.PublishEvent(WorkflowConst.WaitForRestartEvent, WorkflowId, Input);
            };
            _dbcontext.SaveChanges();
            var id = getWorkflowData.GetWorkflowCoreAllData(Input.WorkflowDefinitionId, Input.FormContent);
            return Results_<string>.SuccessResult($"{id}");
        }
        /// <summary>
        /// 审批
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Results_<int> UpAudit(WorkflowAuditInput input)
        {
            var audit = _dbcontext.persistedWorkflowAuditor.FirstOrDefault(p =>
            p.Status == WorkFlowAuditStatus.UnAudited && p.OperateType == OperateType.Approval
                                                 && p.WorkflowId == input.WorkflowId && p.UserId == input.UserId);
            //var audit = _db.PersistedWorkflowAuditor.FirstOrDefault(p => p.UserId == 1);

            if (audit is null)
            {
                return Results_<int>.FailResult("暂无审批任务");
            }

            // 查询当前审批任务的执行节点
            var executePoint =
                _dbcontext.PersistedExecutionPointer.FirstOrDefault(p => audit.ExecutionPointerId.ToString() == p.Id);

            // 发布审批事件
            _workflowHost.PublishEvent(WorkflowConst.WaitForEventName, executePoint.EventKey, input);

            // 修改审批信息
            audit.AuditTime = DateTime.Now;
            audit.Status = input.AuditOperateType == OperateType.Approval
                ? WorkFlowAuditStatus.Pass : string.IsNullOrWhiteSpace(input.RejectToStepId)
                ? WorkFlowAuditStatus.UnApprove : WorkFlowAuditStatus.RejectToHistory;
            audit.Remark = input.Remark;
            audit.OperateType = input.AuditOperateType;
            _dbcontext.SaveChanges();


            return Results_<int>.SuccessResult("审批完毕!!");
        }
        /// <summary>
        /// 驳回发起
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Results_<int> UpRejectData(WorkflowAuditInput input)
        {
            var audit = _dbcontext.persistedWorkflowAuditor.FirstOrDefault(p =>
            p.Status == WorkFlowAuditStatus.UnApprove && p.OperateType == OperateType.Sendback
                                                 && p.WorkflowId == input.WorkflowId && p.UserId == input.UserId);
            // 修改审批信息
            audit.AuditTime = DateTime.Now;
            audit.Status = WorkFlowAuditStatus.UnAudited;
            audit.Remark = input.Remark;
            audit.OperateType = OperateType.Approval;
            _dbcontext.SaveChanges();
            return Results_<int>.SuccessResult("发起成功");
        }
    }
}
